package cn.kivensoft.util;

/** int数组类, 动态扩展
 * @author kiven lee
 * @version 1.0
 */
public class IntArray extends FastArray<int[]> {

	public IntArray() {
		super();
	}

	/** 构造函数
	 * @param capacity 初始容量大小
	 */
	public IntArray(int capacity) {
		super(capacity);
	}

	@Override
	protected int[] newArray(int capacity) {
		return new int[capacity];
	}

	@Override
	protected int[][] newHighArray(int size) {
		return new int[size][];
	}

	/** 返回value所在位置
	 * @param value 要搜索的值
	 * @return -1表示未找到, 其它值表示索引位置
	 */
	public int indexOf(int value) {
		return indexOf(value, 0, _length);
	}

	/** 返回指定区间内value所在位置
	 * @param value 要搜索的值
	 * @param begin 起始位置
	 * @param end 结束位置
	 * @return -1表示未找到, 其它值表示索引位置
	 */
	public int indexOf(int value, int begin, int end) {
		IntNumber result = new IntNumber(-1);
		forEach(begin, end, 0, (va, off, len, ret) -> {
			for (int i = off, imax = off + len; i < imax; ++i) {
				if (va[i] == value) {
					result.setValue(ret + i);
					return -1;
				}
			}
			return ret + len;
		});
		return result.getValue();
	}

	/** 从后面开始查找value第一次出现的位置
	 * @param value 要搜索的值
	 * @return -1表示未找到, 否则返回找到的索引位置
	 */
	public int lastIndexOf(int value) {
		for (int i = _length - 1; i >= 0;) {
			int[] sub = _high[i >> B1];
			int start = i & M1;
			for (int j = start; j >= 0; --j)
				 if (value == sub[j]) return i + j - start;
			i -= start + 1;
		}
		return -1;
	}

	/** 判断是否包含value */
	public boolean contains(final int value) {
		return indexOf(value) != -1;
	}

	/** 获取指定位置的元素 */
	final public int get(int index) {
		return index < C1 ? _low[index] : _high[index >> B1][index & M1];
	}

	/** 设置指定位置的元素 */
	final public void set(int index, int value) {
		if (index < C1) _low[index] = value;
		else _high[index >> B1][index & M1] = value;
	}

	/** 添加一个元素 */
	final public void add(int value) {
		if (_length >= _capacity) increaseCapacity();
		_high[_length >> B1][_length & M1] = value;
		++_length;
	}

	/** 从指定位置开始, 用value填充count次
	 * @param value 要填充的值
	 * @param pos 起始位置
	 * @param count 填充次数
	 */
	public void fill(int value, int pos, int count) {
		int newLen = pos + count;
		if (newLen >= _capacity) increaseCapacity(newLen);
		forEach(pos, newLen, 0, (va, off, len, ret) -> {
			for (int i = off, imax = off + len; i < imax; ++i)
				va[i] = value;
			return 0;
		});
		if (newLen > _length) _length = newLen;
	}

	/** 在指定位置插入数组
	 * @param index 插入的起始位置
	 * @param src 源数组
	 * @param srcBegin 源起始位置
	 * @param srcEnd 源结束位置
	 */
	@Override
	final public void insert(int index, int[] src, int srcBegin, int srcEnd) {
		if (src == null || src.length == 0) return;
		int srcLen = srcEnd - srcBegin, newLen = _length + srcLen;
		if (newLen > _capacity) increaseCapacity(newLen);
		for (int i = _length - 1, j = newLen - 1; i >= index; --i, --j)
			_high[j >> B1][j & M1] = _high[i >> B1][i & M1];
		for (int i = index, imax = index + srcLen, j = srcBegin; i < imax; ++i, ++j)
			_high[i >> B1][i & M1] = src[j];
		_length = newLen;
	}

	/** 删除指定区间的元素, 后面的元素会前移, 长度会自动减少
	 * @param begin 起始位置
	 * @param end 结束位置
	 */
	@Override
	final public void delete(int begin, int end) {
		for (int i = end, j = begin; i < _length; ++i, ++j)
			_high[j >> B1][j & M1] = _high[i >> B1][i & M1];
		_length -= end - begin;
	}

}
